/**
 * 页面地址枚举
 */
export enum Pages {
  /**
   * 可能外部直接进入 & tabbar
   */
  首页 = '/pages/home/index',
  失去网络 = '/pages/results/network_error',
}

export const tabberArr: Pages[] = []

interface IRoute {
  /**
   * 路由类型
   */
  type: ENUM_ROUTE_TYPE
  /**
   * 路由路径
   */
  url: string
  /**
   * 路由参数
   */
  params?: Record<string, any>
  /**
   * 回退的层数 uni.navigateBack
   * @default 1
   */
  delta?: number
  /**
   * 是否编码
   */
  encode?: boolean
}

/**
 * 路由类型
 */
export enum ENUM_ROUTE_TYPE {
  TO = 'navigateTo',
  REDIRECT = 'redirectTo',
  TAB = 'switchTab',
  RELAUNCH = 'reLaunch',
  BACK = 'navigateBack',
}

const params2Url = (params: Record<string, any>, encode = false) => {
  const arr = []
  for (const key in params)
    arr.push(`${key}=${encode ? encodeURIComponent(params[key]) : params[key]}`)

  return arr.join('&')
}

let isNavigateTo = false

/**
 * 路由跳转
 */
export function route({ type, url, params, delta = 1, encode }: IRoute) {
  if (type !== ENUM_ROUTE_TYPE.BACK && params)
    url = `${url}?${params2Url(params, encode)}`

  switch (type) {
    case ENUM_ROUTE_TYPE.TO:
      if (!isNavigateTo) {
        isNavigateTo = true
        uni.navigateTo({
          url,
          complete: () => {
            isNavigateTo = false
          },
        })
      }
      break

    case ENUM_ROUTE_TYPE.REDIRECT:
      uni.redirectTo({
        url,
      })
      break

    case ENUM_ROUTE_TYPE.TAB:
      uni.switchTab({
        url,
      })
      break

    case ENUM_ROUTE_TYPE.RELAUNCH:
      uni.reLaunch({
        url,
      })
      break
    case ENUM_ROUTE_TYPE.BACK:
      uni.navigateBack({
        delta,
        success(result) {
          console.log(result)
        },
        fail(result) {
          console.log(result)
        },
      })
      break

    default:
      break
  }
}

export function to(url: Pages, params?: Record<string, any>, encode?: boolean) {
  if (tabberArr.includes(url)) {
    tabbar(url, params, encode)
  }
  else {
    route({
      type: ENUM_ROUTE_TYPE.TO,
      url,
      params,
      encode,
    })
  }
}

export function redirect(url: Pages, params?: Record<string, any>, encode?: boolean) {
  if (tabberArr.includes(url)) {
    tabbar(url, params, encode)
  }
  else {
    route({
      type: ENUM_ROUTE_TYPE.REDIRECT,
      url,
      params,
      encode,
    })
  }
}

export function tabbar(url: Pages, params?: Record<string, any>, encode?: boolean) {
  if (tabberArr.includes(url)) {
    route({
      type: ENUM_ROUTE_TYPE.TAB,
      url,
      params,
      encode,
    })
  }
  else {
    to(url, params, encode)
  }
}

export function relaunch(url: Pages, params?: Record<string, any>, encode?: boolean) {
  route({
    type: ENUM_ROUTE_TYPE.RELAUNCH,
    url,
    params,
    encode,
  })
}

export function back(delta = 1) {
  route({
    type: ENUM_ROUTE_TYPE.BACK,
    delta,
    url: '',
  })
}
